package com.godliu.file.demo.utils;

import com.godliu.file.demo.pojo.BaseFile;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.*;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
public class ImgUtils {
    public static String IMAGE_DEFAULT_EXTENSION = ".jpg,.png,.jpeg,.gif,.bmp";

    /**
     * 根据文件名后缀判断是否是图片
     *
     * @param fileExtension 文件后缀名，如 .jpg
     * @return true 是图片 false 不是图片
     */
    public static boolean isImage(String fileExtension) {
        if (StringUtils.isNullOrEmpty(fileExtension)) {
            log.error("fileExtension : " + fileExtension);
            return false;
        }
        if (IMAGE_DEFAULT_EXTENSION.contains(fileExtension)) {
            log.error("file is not image : " + fileExtension);
            return false;
        }
        return true;
    }

    /**
     * 根据文件名后缀判断是否是图片
     *
     * @param file 文件对象
     * @return true 是图片 false 不是图片
     */
    public static boolean isImage(File file) {
        return isImage(file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf(".")).toLowerCase());
    }

    /**
     * 获取图片的长度和高度
     *
     * @return (异常返回null)
     * Map<String,Integer>
     * put("width", width)
     * put("height", height)
     */
    public static Map<String, Integer> getImageWidthHeight(File file) {
        if (!isImage(file)) return null;
        Map<String, Integer> returnValue = new HashMap<>();
        try {
            BufferedImage bufferedImage = ImageIO.read(file);
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            returnValue.put("width", width);
            returnValue.put("height", height);
        } catch (Exception e) {
            log.error("获取图片的长度和高度错误：", e);
        }
        return returnValue;
    }

    /**
     * 压缩图片, 等比压缩至符合要求的最大宽度，最大高度
     *
     * @param filePath     原图路径
     * @param maxpicwidth  最大宽度
     * @param maxpicheight 最大高度
     * @param bf           压缩后新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return 是否成功压缩
     */
    public static boolean compressImgMaxSize(String filePath, String maxpicwidth, String maxpicheight, BaseFile bf) {
        return compressImgMaxSize(new File(filePath), maxpicwidth, maxpicheight, bf);
    }


    /**
     * 压缩图片, 等比压缩至符合要求的最大宽度，最大高度
     *
     * @param file         原图
     * @param maxpicwidth  最大宽度
     * @param maxpicheight 最大高度
     * @param bf           压缩后新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return 是否成功压缩
     */
    public static boolean compressImgMaxSize(File file, String maxpicwidth, String maxpicheight, BaseFile bf) {
        log.info("compressImgMaxSize...");
        if (StringUtils.isNullOrEmpty(maxpicwidth) && StringUtils.isNullOrEmpty(maxpicheight)) {
            log.error("check params maxpicwidth and maxpicheight is right");
            return false;
        }
        if (!isImage(file)) return false;

        try {
            BufferedImage bufferedImage = ImageIO.read(file);
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            double rate = 0;//需要压缩的比例
            if (!StringUtils.isNullOrEmpty(maxpicwidth)) {
                double maxw = Double.valueOf(maxpicwidth);
                if (width > maxw) {
                    double _rate = width / maxw;
                    if (_rate > rate) rate = _rate;
                }
            }
            if (!StringUtils.isNullOrEmpty(maxpicheight)) {
                double maxh = Double.valueOf(maxpicheight);
                if (height > maxh) {
                    double _rate = height / maxh;
                    if (_rate > rate) rate = _rate;
                }
            }
            if (rate > 0) {
                int newWidth = (int) (width / rate);
                int newHeight = (int) (height / rate);
                return compressImgSize(file, newWidth, newHeight, bf);
            }

        } catch (Exception ex) {
            log.error("压缩图片错误：", ex);
            return false;
        } finally {
            file = null;
        }
        return false;
    }

    /**
     * 按比例压缩图片长宽
     *
     * @param filePath 原图路径
     * @param rate     比例
     * @param bf       压缩后新的图片信息
     *                 如果为null，则在原图压缩
     *                 如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                 如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return 是否成功压缩
     */
    public static boolean compressImgRate(String filePath, float rate, BaseFile bf) {
        return compressImgRate(new File(filePath), rate, bf);
    }

    /**
     * 按比例压缩图片长宽
     *
     * @param file 原图
     * @param rate 比例
     * @param bf   压缩后新的图片信息
     *             如果为null，则在原图压缩
     *             如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *             如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return 是否成功压缩
     */
    public static boolean compressImgRate(File file, float rate, BaseFile bf) {
        if (rate <= 0) return false;
        Map<String, Integer> wh = getImageWidthHeight(file);
        if (wh == null) return false;
        Float newWidth = wh.get("width") * rate;
        Float newHeight = wh.get("height") * rate;
        return compressImgSize(file, newWidth.intValue(), newHeight.intValue(), bf);
    }

    /**
     * 压缩图片至指定长宽
     *
     * @param filePath 原图路径
     * @param width    指定长
     * @param height   指定宽
     * @param bf       压缩后新的图片信息
     *                 如果为null，则在原图压缩
     *                 如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                 如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return 是否成功压缩
     */
    public static boolean compressImgSize(String filePath, int width, int height, BaseFile bf) {
        return compressImgSize(new File(filePath), width, height, bf);
    }

    /**
     * 压缩图片至指定长宽
     *
     * @param file   原图
     * @param width  指定长
     * @param height 指定宽
     * @param bf     压缩后新的图片信息
     *               如果为null，则在原图压缩
     *               如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *               如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return 是否成功压缩
     */
    public static boolean compressImgSize(File file, int width, int height, BaseFile bf) {
        log.info("compressImgSize...");
        if (width == 0 || height == 0) {
            log.error("check params width and height is right");
            return false;
        }
        String fileExtension = FileUtils.getExtension(file);
        if (!isImage(fileExtension)) {
            return false;
        }
        //目标文件路径
        String outFilePath = FileUtils.getOutFilePath(file, bf);
        try {
            BufferedImage bufferedImage = ImageIO.read(file);
            Image image = bufferedImage.getScaledInstance(width, height, Image.SCALE_DEFAULT);
            BufferedImage targetImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics graphics = targetImage.getGraphics();
            graphics.drawImage(image, 0, 0, null);
            graphics.dispose();

            File outFile = new File(outFilePath);
            ImageIO.write(targetImage, fileExtension.substring(1), outFile);

            if (bf != null) {
                bf.setExtension(fileExtension);
                bf.setHeight(height);
                bf.setWidth(width);
                bf.setLengthK(outFile.length() / 1024);
                log.info(bf.toString());
            }
        } catch (Exception ex) {
            log.error("压缩图片错误：", ex);
            return false;
        } finally {
            file = null;
        }
        return true;
    }

    /**
     * 压缩图片质量
     *
     * @param filePath 压缩前的原文件路径
     * @param quality  压缩比 0--1
     * @param bf       压缩后新的图片信息
     *                 如果为null，则在原图压缩
     *                 如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                 如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     */
    public static boolean compressImgQuality(String filePath, float quality, BaseFile bf) {
        return compressImgQuality(new File(filePath), quality, bf);
    }

    /**
     * 压缩图片质量
     *
     * @param file    压缩前的原文件
     * @param quality 压缩比 0--1
     * @param bf      压缩后新的图片信息
     *                如果为null，则在原图压缩
     *                如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     */
    public static boolean compressImgQuality(File file, float quality, BaseFile bf) {
        if (quality <= 0 || quality >= 1f) {
            log.error("compressImgQuality... quality is :" + quality);
            return false;
        }
        String fileExtension = FileUtils.getExtension(file);
        if (!isImage(fileExtension)) {
            return false;
        }

        ImageOutputStream ios = null;
        ImageWriter imageWriter = null;

        //目标文件路径
        String outFilePath = FileUtils.getOutFilePath(file, bf);
        try {
            //source file
            BufferedImage bufferedImage = ImageIO.read(file);
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            BufferedImage image_to_save = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            image_to_save.getGraphics().drawImage(bufferedImage.getScaledInstance(width, height, Image.SCALE_DEFAULT), 0, 0, null);

            //imageWriter
            ios = ImageIO.createImageOutputStream(new FileOutputStream(outFilePath));
            imageWriter = ImageIO.getImageWritersBySuffix("jpg").next();
            imageWriter.setOutput(ios);
            IIOMetadata imageMetaData = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image_to_save), null);
            JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter.getDefaultWriteParam();
            jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
            jpegParams.setCompressionQuality(quality);
            imageWriter.write(imageMetaData, new IIOImage(image_to_save, null, null), null);

            if (bf != null) {
                bf.setExtension(fileExtension);
                bf.setHeight(height);
                bf.setWidth(width);
                bf.setLengthK(new File(outFilePath).length() / 1024);
                log.info(bf.toString());
            }

        } catch (Exception ex) {
            log.error("压缩图片质量错误：", ex);
            return false;
        } finally {
            try {
                if (ios != null) ios.close();
                if (imageWriter != null) imageWriter.dispose();
            } catch (IOException ex) {
                log.error("压缩图片质量错误：", ex);
            }
        }
        return true;
    }

    /**
     * 去除图片中的某个颜色值(即把这个颜色变透明)，只处理 png jpg
     *
     * @param filePath
     * @param color
     * @param bf       压缩后新的图片信息
     *                 如果为null，则在原图压缩
     *                 如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                 如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean removeImageColor(String filePath, Color color, BaseFile bf) {
        return removeImageColor(new File(filePath), color, bf);
    }

    /**
     * 去除图片中的某个颜色值(即把这个颜色变透明)，只处理 png jpg
     *
     * @param color
     * @param bf    压缩后新的图片信息
     *              如果为null，则在原图压缩
     *              如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *              如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean removeImageColor(File file, Color color, BaseFile bf) {
        log.info("removeImageColor...");

        String fileExtension = FileUtils.getExtension(file);
        if (!(".png".equals(fileExtension) || ".jpg".equals(fileExtension))) {
            log.error("只处理png jpg格式的图片");
            return false;
        }
        //目标文件路径
        String outFilePath = FileUtils.getOutFilePath(file, bf);
        try {
            BufferedImage srcBufferedImage = ImageIO.read(file);
            int x = srcBufferedImage.getWidth(null);
            int y = srcBufferedImage.getHeight(null);

            BufferedImage targetBufferedImage = new BufferedImage(x, y, BufferedImage.TYPE_4BYTE_ABGR);
            WritableRaster rasterDes = targetBufferedImage.getRaster();
            int[] des = new int[4];
            while (--x >= 0) {
                for (int j = 0; j < y; ++j) {
                    int rgb = srcBufferedImage.getRGB(x, j);
                    int sr, sg, sb;
                    sr = (rgb & 0xFF0000) >> 16;
                    sg = (rgb & 0xFF00) >> 8;
                    sb = rgb & 0xFF;
                    if (sr == color.getRed() && sg == color.getGreen()
                            && sb == color.getBlue()) {
                        des[3] = 0;
                    } else {
                        des[0] = sr;
                        des[1] = sg;
                        des[2] = sb;
                        des[3] = 255;
                    }
                    rasterDes.setPixel(x, j, des);
                }
            }

            File outFile = new File(outFilePath);
            ImageIO.write(targetBufferedImage, fileExtension.substring(1), outFile);

            if (bf != null) {
                bf.setExtension(fileExtension);
                bf.setHeight(x);
                bf.setWidth(y);
                bf.setLengthK(outFile.length() / 1024);
                log.info(bf.toString());
            }
        } catch (Exception ex) {
            log.error("处理图片错误：", ex);
            return false;
        } finally {
            file = null;
        }
        return true;
    }

    /**
     * 在图片中截取一部分
     *
     * @param filePath 原图
     * @param x        起点坐标
     * @param y        起点坐标
     * @param width    宽度
     * @param height   高度
     * @param bf       新的图片信息
     *                 如果为null，则在原图压缩
     *                 如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                 如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean cutImage(String filePath, int x, int y, int width, int height, BaseFile bf) {
        return cutImage(new File(filePath), x, y, width, height, bf);
    }

    /**
     * 在图片中截取一部分
     *
     * @param x      起点坐标
     * @param y      起点坐标
     * @param width  宽度
     * @param height 高度
     * @param bf     新的图片信息
     *               如果为null，则在原图压缩
     *               如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *               如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean cutImage(File file, int x, int y, int width, int height, BaseFile bf) {
        log.info("cutImage...");
        if (width == 0 || height == 0) {
            log.error("check params width and height is right");
            return false;
        }
        String fileExtension = FileUtils.getExtension(file);
        if (!isImage(fileExtension)) {
            return false;
        }
        //目标文件路径
        String outFilePath = FileUtils.getOutFilePath(file, bf);

        FileInputStream fis = null;
        ImageInputStream iis = null;
        try {
            //读取图片文件
            fis = new FileInputStream(file);
            Iterator it = ImageIO.getImageReadersByFormatName(fileExtension.substring(1));
            ImageReader reader = (ImageReader) it.next();
            //获取图片流
            iis = ImageIO.createImageInputStream(fis);
            reader.setInput(iis, true);
            ImageReadParam param = reader.getDefaultReadParam();
            //定义一个矩形
            Rectangle rect = new Rectangle(x, y, width, height);
            //提供一个 BufferedImage，将其用作解码像素数据的目标。
            param.setSourceRegion(rect);

            BufferedImage targetBufferedImage = reader.read(0, param);
            //保存新图片
            File outFile = new File(outFilePath);
            ImageIO.write(targetBufferedImage, fileExtension.substring(1), outFile);

            if (bf != null) {
                bf.setExtension(fileExtension);
                bf.setHeight(x);
                bf.setWidth(y);
                bf.setLengthK(outFile.length() / 1024);
                log.info(bf.toString());
            }
        } catch (Exception ex) {
            log.error("处理图片错误：", ex);
            return false;
        } finally {
            try {
                if (fis != null)
                    fis.close();
                if (iis != null)
                    iis.close();
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }
        return true;
    }

    /**
     * 横向拼接多张图片，建议使用同一格式的图片（后缀），高度必须一致
     *
     * @param pics 多张图片的地址
     * @param bf   新的图片信息
     *             如果为null，则在原图压缩
     *             如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *             如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean joinImagesH(String[] pics, BaseFile bf) {
        log.info("joinImagesH...");
        if (pics == null || pics.length <= 1) {
            log.error("pics size <= 1");
            return false;
        }
        try {
            int len = pics.length;
            File[] src = new File[len];
            BufferedImage[] images = new BufferedImage[len];
            int[][] imageArrays = new int[len][];
            for (int i = 0; i < len; i++) {
                src[i] = new File(pics[i]);
                images[i] = ImageIO.read(src[i]);
                int width = images[i].getWidth();
                int height = images[i].getHeight();
                imageArrays[i] = new int[width * height];// 从图片中读取RGB
                imageArrays[i] = images[i].getRGB(0, 0, width, height, imageArrays[i], 0, width);
            }
            //目标文件路径
            String outFilePath = FileUtils.getOutFilePath(src[0], bf);
            String fileExtension = FileUtils.getExtension(src[0]);

            int dst_width = 0;
            int dst_height = images[0].getHeight();
            for (int i = 0; i < images.length; i++) {
                dst_height = dst_height > images[i].getHeight() ? dst_height : images[i].getHeight();
                dst_width += images[i].getWidth();
            }
            if (dst_height < 1) {
                log.error("pics dst_height < 1");
                return false;
            }
            /*
             * 生成新图片
             */
            BufferedImage ImageNew = new BufferedImage(dst_width, dst_height, BufferedImage.TYPE_INT_RGB);
            int width_i = 0;
            for (int i = 0; i < images.length; i++) {
                ImageNew.setRGB(width_i, 0, images[i].getWidth(), dst_height, imageArrays[i], 0, images[i].getWidth());
                width_i += images[i].getWidth();
            }
            File outFile = new File(outFilePath);
            ImageIO.write(ImageNew, fileExtension.substring(1), outFile);
            if (bf != null) {
                bf.setExtension(fileExtension);
                Map<String, Integer> wh = getImageWidthHeight(outFile);
                bf.setHeight(wh.get("height"));
                bf.setWidth(wh.get("width"));
                bf.setLengthK(outFile.length() / 1024);
                log.info(bf.toString());
            }
        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return false;
    }

    /**
     * 纵向拼接多张图片，建议使用同一格式的图片（后缀），宽度必须一致
     *
     * @param pics 多张图片的地址
     * @param bf   新的图片信息
     *             如果为null，则在原图压缩
     *             如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *             如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean joinImagesV(String[] pics, BaseFile bf) {
        log.info("joinImagesV...");
        if (pics == null || pics.length <= 1) {
            log.error("pics size <= 1");
            return false;
        }
        try {
            int len = pics.length;
            File[] src = new File[len];
            BufferedImage[] images = new BufferedImage[len];
            int[][] imageArrays = new int[len][];
            for (int i = 0; i < len; i++) {
                src[i] = new File(pics[i]);
                images[i] = ImageIO.read(src[i]);
                int width = images[i].getWidth();
                int height = images[i].getHeight();
                imageArrays[i] = new int[width * height];// 从图片中读取RGB
                imageArrays[i] = images[i].getRGB(0, 0, width, height, imageArrays[i], 0, width);
            }
            //目标文件路径
            String outFilePath = FileUtils.getOutFilePath(src[0], bf);
            String fileExtension = FileUtils.getExtension(src[0]);

            int dst_height = 0;
            int dst_width = images[0].getWidth();
            for (int i = 0; i < images.length; i++) {
                dst_width = dst_width > images[i].getWidth() ? dst_width : images[i].getWidth();
                dst_height += images[i].getHeight();
            }
            if (dst_height < 1) {
                log.error("pics dst_height < 1");
                return false;
            }
            /*
             * 生成新图片
             */
            BufferedImage ImageNew = new BufferedImage(dst_width, dst_height, BufferedImage.TYPE_INT_RGB);
            int height_i = 0;
            for (int i = 0; i < images.length; i++) {
                ImageNew.setRGB(0, height_i, dst_width, images[i].getHeight(), imageArrays[i], 0, dst_width);
                height_i += images[i].getHeight();
            }
            File outFile = new File(outFilePath);
            ImageIO.write(ImageNew, fileExtension.substring(1), outFile);
            if (bf != null) {
                bf.setExtension(fileExtension);
                Map<String, Integer> wh = getImageWidthHeight(outFile);
                bf.setHeight(wh.get("height"));
                bf.setWidth(wh.get("width"));
                bf.setLengthK(outFile.length() / 1024);
                log.info(bf.toString());
            }
        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return false;
    }

    /**
     * 在原图上叠加一张另外图片（常见于加水印）
     *
     * @param srcImagePath 原图
     * @param addImagePath 叠加图片
     * @param alpha        透明度 0--1，1为不透明
     * @param x            起始坐标
     * @param y            起始坐标
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean addImage(String srcImagePath, String addImagePath, float alpha, int x, int y, BaseFile bf) {
        log.info("addImage...");
        if (StringUtils.isEmpty(srcImagePath) || StringUtils.isEmpty(addImagePath)) {
            log.error("原图或者叠加图片不能为空");
            return false;
        }

        try {
            File srcFile = new File(srcImagePath);
            if (!isImage(srcFile)) return false;
            BufferedImage srcImage = ImageIO.read(srcFile);

            File addFile = new File(addImagePath);
            if (!isImage(addFile)) return false;
            BufferedImage addImage = ImageIO.read(addFile);

            addImage(srcImage, addImage, alpha, x, y, srcFile, bf);

        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 在原图上叠加一张另外图片（常见于加水印）
     *
     * @param srcImagePath 原图
     * @param addImagePath 叠加图片
     * @param alpha        透明度 0--1，1为不透明
     * @param space        间距，距离边缘多少像素
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean addImageLeftTop(String srcImagePath, String addImagePath, float alpha, int space, BaseFile bf) {
        log.info("addImageLeftTop...");
        if (StringUtils.isEmpty(srcImagePath) || StringUtils.isEmpty(addImagePath)) {
            log.error("原图或者叠加图片不能为空");
            return false;
        }

        try {
            File srcFile = new File(srcImagePath);
            if (!isImage(srcFile)) return false;
            BufferedImage srcImage = ImageIO.read(srcFile);

            File addFile = new File(addImagePath);
            if (!isImage(addFile)) return false;
            BufferedImage addImage = ImageIO.read(addFile);

            addImage(srcImage, addImage, alpha, space, space, srcFile, bf);

        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 在原图上叠加一张另外图片（常见于加水印）
     *
     * @param srcImagePath 原图
     * @param addImagePath 叠加图片
     * @param alpha        透明度 0--1，1为不透明
     * @param space        间距，距离边缘多少像素
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean addImageLeftCenter(String srcImagePath, String addImagePath, float alpha, int space, BaseFile bf) {
        log.info("addImageLeftCenter...");
        if (StringUtils.isEmpty(srcImagePath) || StringUtils.isEmpty(addImagePath)) {
            log.error("原图或者叠加图片不能为空");
            return false;
        }

        try {
            File srcFile = new File(srcImagePath);
            if (!isImage(srcFile)) return false;
            BufferedImage srcImage = ImageIO.read(srcFile);

            File addFile = new File(addImagePath);
            if (!isImage(addFile)) return false;
            BufferedImage addImage = ImageIO.read(addFile);

            int x = space;
            int y = (srcImage.getHeight() - addImage.getHeight()) / 2;

            addImage(srcImage, addImage, alpha, x, y, srcFile, bf);

        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 在原图上叠加一张另外图片（常见于加水印）
     *
     * @param srcImagePath 原图
     * @param addImagePath 叠加图片
     * @param alpha        透明度 0--1，1为不透明
     * @param space        间距，距离边缘多少像素
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean addImageLeftBottom(String srcImagePath, String addImagePath, float alpha, int space, BaseFile bf) {
        log.info("addImageLeftBottom...");
        if (StringUtils.isEmpty(srcImagePath) || StringUtils.isEmpty(addImagePath)) {
            log.error("原图或者叠加图片不能为空");
            return false;
        }

        try {
            File srcFile = new File(srcImagePath);
            if (!isImage(srcFile)) return false;
            BufferedImage srcImage = ImageIO.read(srcFile);

            File addFile = new File(addImagePath);
            if (!isImage(addFile)) return false;
            BufferedImage addImage = ImageIO.read(addFile);

            int x = space;
            int y = srcImage.getHeight() - addImage.getHeight() - space;

            addImage(srcImage, addImage, alpha, x, y, srcFile, bf);

        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 在原图上叠加一张另外图片（常见于加水印）
     *
     * @param srcImagePath 原图
     * @param addImagePath 叠加图片
     * @param alpha        透明度 0--1，1为不透明
     * @param space        间距，距离边缘多少像素
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean addImageBottomCenter(String srcImagePath, String addImagePath, float alpha, int space, BaseFile bf) {
        log.info("addImageBottomCenter...");
        if (StringUtils.isEmpty(srcImagePath) || StringUtils.isEmpty(addImagePath)) {
            log.error("原图或者叠加图片不能为空");
            return false;
        }

        try {
            File srcFile = new File(srcImagePath);
            if (!isImage(srcFile)) return false;
            BufferedImage srcImage = ImageIO.read(srcFile);

            File addFile = new File(addImagePath);
            if (!isImage(addFile)) return false;
            BufferedImage addImage = ImageIO.read(addFile);

            int x = (srcImage.getWidth() - addImage.getWidth()) / 2;
            int y = srcImage.getHeight() - addImage.getHeight() - space;

            addImage(srcImage, addImage, alpha, x, y, srcFile, bf);

        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 在原图上叠加一张另外图片（常见于加水印）
     *
     * @param srcImagePath 原图
     * @param addImagePath 叠加图片
     * @param alpha        透明度 0--1，1为不透明
     * @param space        间距，距离边缘多少像素
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean addImageBottomRight(String srcImagePath, String addImagePath, float alpha, int space, BaseFile bf) {
        log.info("addImageBottomRight...");
        if (StringUtils.isEmpty(srcImagePath) || StringUtils.isEmpty(addImagePath)) {
            log.error("原图或者叠加图片不能为空");
            return false;
        }

        try {
            File srcFile = new File(srcImagePath);
            if (!isImage(srcFile)) return false;
            BufferedImage srcImage = ImageIO.read(srcFile);

            File addFile = new File(addImagePath);
            if (!isImage(addFile)) return false;
            BufferedImage addImage = ImageIO.read(addFile);

            int x = srcImage.getWidth() - addImage.getWidth() - space;
            int y = srcImage.getHeight() - addImage.getHeight() - space;

            addImage(srcImage, addImage, alpha, x, y, srcFile, bf);

        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 在原图上叠加一张另外图片（常见于加水印）
     *
     * @param srcImagePath 原图
     * @param addImagePath 叠加图片
     * @param alpha        透明度 0--1，1为不透明
     * @param space        间距，距离边缘多少像素
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean addImageRightCenter(String srcImagePath, String addImagePath, float alpha, int space, BaseFile bf) {
        log.info("addImageRightCenter...");
        if (StringUtils.isEmpty(srcImagePath) || StringUtils.isEmpty(addImagePath)) {
            log.error("原图或者叠加图片不能为空");
            return false;
        }

        try {
            File srcFile = new File(srcImagePath);
            if (!isImage(srcFile)) return false;
            BufferedImage srcImage = ImageIO.read(srcFile);

            File addFile = new File(addImagePath);
            if (!isImage(addFile)) return false;
            BufferedImage addImage = ImageIO.read(addFile);

            int x = srcImage.getWidth() - addImage.getWidth() - space;
            int y = (srcImage.getHeight() - addImage.getHeight()) / 2;

            addImage(srcImage, addImage, alpha, x, y, srcFile, bf);

        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 在原图上叠加一张另外图片（常见于加水印）
     *
     * @param srcImagePath 原图
     * @param addImagePath 叠加图片
     * @param alpha        透明度 0--1，1为不透明
     * @param space        间距，距离边缘多少像素
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean addImageRightTop(String srcImagePath, String addImagePath, float alpha, int space, BaseFile bf) {
        log.info("addImageRightTop...");
        if (StringUtils.isEmpty(srcImagePath) || StringUtils.isEmpty(addImagePath)) {
            log.error("原图或者叠加图片不能为空");
            return false;
        }

        try {
            File srcFile = new File(srcImagePath);
            if (!isImage(srcFile)) return false;
            BufferedImage srcImage = ImageIO.read(srcFile);

            File addFile = new File(addImagePath);
            if (!isImage(addFile)) return false;
            BufferedImage addImage = ImageIO.read(addFile);

            int x = srcImage.getWidth() - addImage.getWidth() - space;
            int y = space;

            addImage(srcImage, addImage, alpha, x, y, srcFile, bf);

        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 在原图上叠加一张另外图片（常见于加水印）
     *
     * @param srcImagePath 原图
     * @param addImagePath 叠加图片
     * @param alpha        透明度 0--1，1为不透明
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean addImageCenterCenter(String srcImagePath, String addImagePath, float alpha, BaseFile bf) {
        log.info("addImageCenterCenter...");
        if (StringUtils.isEmpty(srcImagePath) || StringUtils.isEmpty(addImagePath)) {
            log.error("原图或者叠加图片不能为空");
            return false;
        }

        try {
            File srcFile = new File(srcImagePath);
            if (!isImage(srcFile)) return false;
            BufferedImage srcImage = ImageIO.read(srcFile);

            File addFile = new File(addImagePath);
            if (!isImage(addFile)) return false;
            BufferedImage addImage = ImageIO.read(addFile);

            int x = (srcImage.getWidth() - addImage.getWidth()) / 2;
            int y = (srcImage.getHeight() - addImage.getHeight()) / 2;

            addImage(srcImage, addImage, alpha, x, y, srcFile, bf);

        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 在原图上叠加一张另外图片（常见于加水印）
     *
     * @param srcImagePath 原图
     * @param addImagePath 叠加图片
     * @param alpha        透明度 0--1，1为不透明
     * @param space        间距，距离边缘多少像素
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean addImageTopCenter(String srcImagePath, String addImagePath, float alpha, int space, BaseFile bf) {
        log.info("addImageTopCenter...");
        if (StringUtils.isEmpty(srcImagePath) || StringUtils.isEmpty(addImagePath)) {
            log.error("原图或者叠加图片不能为空");
            return false;
        }

        try {
            File srcFile = new File(srcImagePath);
            if (!isImage(srcFile)) return false;
            BufferedImage srcImage = ImageIO.read(srcFile);

            File addFile = new File(addImagePath);
            if (!isImage(addFile)) return false;
            BufferedImage addImage = ImageIO.read(addFile);

            int x = (srcImage.getWidth() - addImage.getWidth()) / 2;
            int y = space;

            addImage(srcImage, addImage, alpha, x, y, srcFile, bf);

        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 在原图上叠加一张另外图片（常见于加水印）,内部方法，被调用
     *
     * @param srcImage 原图
     * @param addImage 叠加图片
     * @param alpha    透明度 0--1，1为不透明
     * @param x        起始坐标
     * @param y        起始坐标
     * @throws Exception
     */
    private static void addImage(BufferedImage srcImage, BufferedImage addImage, float alpha, int x, int y, File srcFile, BaseFile bf) throws Exception {
        //创建java2D对象
        Graphics2D g2d = srcImage.createGraphics();
        //用源图像填充背景
        g2d.drawImage(srcImage, 0, 0, srcImage.getWidth(), srcImage.getHeight(), null, null);

        //设置透明度
        AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
        g2d.setComposite(ac);
        //设置水印图片的起始x/y坐标、宽度、高度
        g2d.drawImage(addImage, x, y, addImage.getWidth(), addImage.getHeight(), null, null);
        g2d.dispose();

        //目标文件路径
        String outFilePath = FileUtils.getOutFilePath(srcFile, bf);
        String fileExtension = FileUtils.getExtension(srcFile);
        File outFile = new File(outFilePath);
        ImageIO.write(srcImage, fileExtension.substring(1), outFile);
        if (bf != null) {
            bf.setExtension(fileExtension);
            bf.setHeight(srcImage.getHeight());
            bf.setWidth(srcImage.getWidth());
            bf.setLengthK(outFile.length() / 1024);
            log.info(bf.toString());
        }
    }

    /**
     * 图片灰化操作
     *
     * @param srcImagePath 原图路径
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean grayImage(String srcImagePath, BaseFile bf) {
        log.info("grayImage...");
        if (StringUtils.isEmpty(srcImagePath)) {
            log.error("原图不能为空");
            return false;
        }
        try {
            File srcFile = new File(srcImagePath);
            BufferedImage src = ImageIO.read(srcFile);
            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
            ColorConvertOp op = new ColorConvertOp(cs, null);
            src = op.filter(src, null);

            String outFilePath = FileUtils.getOutFilePath(srcFile, bf);
            String fileExtension = FileUtils.getExtension(srcFile);
            File outFile = new File(outFilePath);
            ImageIO.write(src, fileExtension.substring(1), outFile);
            if (bf != null) {
                bf.setExtension(fileExtension);
                bf.setHeight(src.getHeight());
                bf.setWidth(src.getWidth());
                bf.setLengthK(outFile.length() / 1024);
                log.info(bf.toString());
            }
        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 在原图上叠加文字
     *
     * @param srcImagePath 原图
     * @param alpha        透明度 0--1，1为不透明
     * @param x            起始坐标
     * @param y            起始坐标
     * @param font         字体 例如：宋体
     * @param fontStyle    字体格式 例如：普通样式--Font.PLAIN、粗体--Font.BOLD
     * @param fontSize     字体大小
     * @param color        字体颜色(例如：黑色--Color.BLACK)
     * @param inputWords   显示在图片上的文字
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean addTxt(String srcImagePath, float alpha, int x, int y, String font, int fontStyle, int fontSize, Color color, String inputWords, BaseFile bf) {
        log.info("addTxt...");
        if (StringUtils.isEmpty(srcImagePath)) {
            log.error("原图不能为空");
            return false;
        }
        try {
            File srcFile = new File(srcImagePath);
            BufferedImage image = ImageIO.read(srcFile);
            //创建java2D对象
            Graphics2D g2d = image.createGraphics();
            //用源图像填充背景
            g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null, null);

            //设置透明度
            AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
            g2d.setComposite(ac);
            //设置文字字体名称、样式、大小
            g2d.setFont(new Font(font, fontStyle, fontSize));
            g2d.setColor(color);//设置字体颜色
            g2d.drawString(inputWords, x, y); //输入水印文字及其起始x、y坐标
            g2d.dispose();

            String outFilePath = FileUtils.getOutFilePath(srcFile, bf);
            String fileExtension = FileUtils.getExtension(srcFile);
            File outFile = new File(outFilePath);
            ImageIO.write(image, fileExtension.substring(1), outFile);
            if (bf != null) {
                bf.setExtension(fileExtension);
                bf.setHeight(image.getHeight());
                bf.setWidth(image.getWidth());
                bf.setLengthK(outFile.length() / 1024);
                log.info(bf.toString());
            }
        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 图片上画点
     *
     * @param srcImagePath 原图
     * @param alpha        透明度 0--1，1为不透明
     * @param x            起始坐标
     * @param y            起始坐标
     * @param width        点的宽度 （两者不一致时为椭圆）
     * @param height       点的高度 （两者不一致时为椭圆）
     * @param color        颜色(例如：黑色--Color.BLACK)
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean drawPoint(String srcImagePath, float alpha, int x, int y, int width, int height, Color color, BaseFile bf) {
        log.info("drawPoint...");
        if (StringUtils.isEmpty(srcImagePath)) {
            log.error("原图不能为空");
            return false;
        }
        try {
            //获取源图片
            File srcFile = new File(srcImagePath);
            BufferedImage image = ImageIO.read(srcFile);
            Graphics2D g2d = image.createGraphics();
            //用源图像填充背景
            g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null, null);

            //设置透明度
            AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
            g2d.setComposite(ac);
            g2d.setColor(color);
            //填充一个椭圆形
            g2d.fillOval(x, y, width, height);
            g2d.dispose();

            String outFilePath = FileUtils.getOutFilePath(srcFile, bf);
            String fileExtension = FileUtils.getExtension(srcFile);
            File outFile = new File(outFilePath);
            ImageIO.write(image, fileExtension.substring(1), outFile);
            if (bf != null) {
                bf.setExtension(fileExtension);
                bf.setHeight(image.getHeight());
                bf.setWidth(image.getWidth());
                bf.setLengthK(outFile.length() / 1024);
                log.info(bf.toString());
            }
        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 图片上画多个点
     *
     * @param srcImagePath 原图
     * @param alpha        透明度 0--1，1为不透明
     * @param x            起始坐标
     * @param y            起始坐标
     * @param width        点的宽度 （两者不一致时为椭圆）
     * @param height       点的高度 （两者不一致时为椭圆）
     * @param color        颜色(例如：黑色--Color.BLACK)
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean drawPoints(String srcImagePath, float alpha, int[] x, int[] y, int width, int height, Color color, BaseFile bf) {
        log.info("drawPoints...");
        if (StringUtils.isEmpty(srcImagePath)) {
            log.error("原图不能为空");
            return false;
        }
        try {
            //获取源图片
            File srcFile = new File(srcImagePath);
            BufferedImage image = ImageIO.read(srcFile);
            Graphics2D g2d = image.createGraphics();
            //用源图像填充背景
            g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null, null);

            //设置透明度
            AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
            g2d.setComposite(ac);
            g2d.setColor(color);
            //填充一个椭圆形
            for (int i = x.length - 1; i >= 0; i--) {
                g2d.fillOval(x[i], y[i], width, height);
            }
            g2d.dispose();

            String outFilePath = FileUtils.getOutFilePath(srcFile, bf);
            String fileExtension = FileUtils.getExtension(srcFile);
            File outFile = new File(outFilePath);
            ImageIO.write(image, fileExtension.substring(1), outFile);
            if (bf != null) {
                bf.setExtension(fileExtension);
                bf.setHeight(image.getHeight());
                bf.setWidth(image.getWidth());
                bf.setLengthK(outFile.length() / 1024);
                log.info(bf.toString());
            }
        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }


    /**
     * 图片上画线段
     *
     * @param srcImagePath 原图
     * @param alpha        透明度 0--1，1为不透明
     * @param x            起始坐标
     * @param y            起始坐标
     * @param lineWidth    线的宽度 (最细的几倍)
     * @param color        颜色(例如：黑色--Color.BLACK)
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean drawPolyline(String srcImagePath, float alpha, int[] x, int[] y, float lineWidth, Color color, BaseFile bf) {
        log.info("drawPoints...");
        if (StringUtils.isEmpty(srcImagePath)) {
            log.error("原图不能为空");
            return false;
        }
        try {
            //获取源图片
            File srcFile = new File(srcImagePath);
            BufferedImage image = ImageIO.read(srcFile);
            Graphics2D g2d = image.createGraphics();
            //用源图像填充背景
            g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null, null);

            //设置透明度
            AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
            g2d.setComposite(ac);
            g2d.setColor(color);
            g2d.setStroke(new BasicStroke(lineWidth));
            //填充一个椭圆形
            g2d.drawPolyline(x, y, x.length);
            g2d.dispose();

            String outFilePath = FileUtils.getOutFilePath(srcFile, bf);
            String fileExtension = FileUtils.getExtension(srcFile);
            File outFile = new File(outFilePath);
            ImageIO.write(image, fileExtension.substring(1), outFile);
            if (bf != null) {
                bf.setExtension(fileExtension);
                bf.setHeight(image.getHeight());
                bf.setWidth(image.getWidth());
                bf.setLengthK(outFile.length() / 1024);
                log.info(bf.toString());
            }
        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }

    /**
     * 图片上画多边形
     *
     * @param srcImagePath 原图
     * @param alpha        透明度 0--1，1为不透明
     * @param x            起始坐标
     * @param y            起始坐标
     * @param lineWidth    线的宽度 (最细的几倍)
     * @param color        颜色(例如：黑色--Color.BLACK)
     * @param bgColor      是否背景色填充（false，则是有线段组成多边形，true填充色组成多边形）
     * @param bf           新的图片信息
     *                     如果为null，则在原图压缩
     *                     如果bf对象的newPath值为空，则压缩后的图片名为原图片名加“_”前缀
     *                     如果bf对象指定了newPath值，则压缩后的图片名为指定的图片名
     * @return
     */
    public static boolean drawPolygon(String srcImagePath, float alpha, int[] x, int[] y, float lineWidth, Color color, boolean bgColor, BaseFile bf) {
        log.info("drawPoints...");
        if (StringUtils.isEmpty(srcImagePath)) {
            log.error("原图不能为空");
            return false;
        }
        try {
            //获取源图片
            File srcFile = new File(srcImagePath);
            BufferedImage image = ImageIO.read(srcFile);
            Graphics2D g2d = image.createGraphics();
            //用源图像填充背景
            g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null, null);

            //设置透明度
            AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
            g2d.setComposite(ac);
            g2d.setColor(color);
            g2d.setStroke(new BasicStroke(lineWidth));
            //填充一个椭圆形
            if (bgColor) {
                g2d.fillPolygon(x, y, x.length);
            } else {
                g2d.drawPolygon(x, y, x.length);
            }
            g2d.dispose();

            String outFilePath = FileUtils.getOutFilePath(srcFile, bf);
            String fileExtension = FileUtils.getExtension(srcFile);
            File outFile = new File(outFilePath);
            ImageIO.write(image, fileExtension.substring(1), outFile);
            if (bf != null) {
                bf.setExtension(fileExtension);
                bf.setHeight(image.getHeight());
                bf.setWidth(image.getWidth());
                bf.setLengthK(outFile.length() / 1024);
                log.info(bf.toString());
            }
        } catch (Exception e) {
            log.error("处理图片错误：", e);
            return false;
        }
        return true;
    }
}
